chore(linter): make ruff happy

This commit is contained in:
MingxuanGame
2025-09-13 14:38:29 +00:00
parent c072dde9d5
commit ffe4c5b14d
5 changed files with 108 additions and 132 deletions

View File

@@ -1,4 +1,5 @@
"""V1 API 用户相关模型"""
from __future__ import annotations
from pydantic import BaseModel, Field
@@ -6,11 +7,13 @@ from pydantic import BaseModel, Field
class PlayerStatsHistory(BaseModel):
"""玩家 PP 历史数据"""
pp: list[float] = Field(default_factory=list)
class PlayerModeStats(BaseModel):
"""单个模式的玩家统计数据"""
id: int
mode: int
tscore: int # total_score
@@ -23,10 +26,10 @@ class PlayerModeStats(BaseModel):
total_hits: int
replay_views: int # replays_watched_by_others
xh_count: int # grade_ssh
x_count: int # grade_ss
x_count: int # grade_ss
sh_count: int # grade_sh
s_count: int # grade_s
a_count: int # grade_a
s_count: int # grade_s
a_count: int # grade_a
level: int
level_progress: int
rank: int
@@ -36,11 +39,13 @@ class PlayerModeStats(BaseModel):
class PlayerStatsResponse(BaseModel):
"""玩家统计信息响应 - 包含所有模式"""
stats: dict[str, PlayerModeStats] = Field(default_factory=dict)
class PlayerEventItem(BaseModel):
"""玩家事件项目"""
userId: int
name: str
mapId: int | None = None
@@ -57,11 +62,13 @@ class PlayerEventItem(BaseModel):
class PlayerEventsResponse(BaseModel):
"""玩家事件响应"""
events: list[PlayerEventItem] = Field(default_factory=list)
class PlayerInfo(BaseModel):
"""玩家基本信息"""
id: int
name: str
safe_name: str
@@ -93,11 +100,13 @@ class PlayerInfo(BaseModel):
class PlayerInfoResponse(BaseModel):
"""玩家信息响应"""
info: PlayerInfo
class PlayerAllResponse(BaseModel):
"""玩家完整信息响应 - 包含所有数据"""
info: PlayerInfo
stats: dict[str, PlayerModeStats] = Field(default_factory=dict)
events: list[PlayerEventItem] = Field(default_factory=list)
@@ -105,17 +114,20 @@ class PlayerAllResponse(BaseModel):
class GetPlayerInfoResponse(BaseModel):
"""get_player_info 接口响应"""
status: str = "success"
player: PlayerStatsResponse | PlayerEventsResponse | PlayerInfoResponse | PlayerAllResponse
class PlayerCountData(BaseModel):
"""玩家数量数据"""
online: int
total: int
class GetPlayerCountResponse(BaseModel):
"""get_player_count 接口响应"""
status: str = "success"
counts: PlayerCountData

View File

@@ -1,7 +1,7 @@
from __future__ import annotations
from . import beatmap, replay, score, user, public_user # noqa: F401
from .router import router as api_v1_router
from . import beatmap, public_user, replay, score, user # noqa: F401
from .public_router import public_router as api_v1_public_router
from .router import router as api_v1_router
__all__ = ["api_v1_router", "api_v1_public_router"]
__all__ = ["api_v1_public_router", "api_v1_router"]

View File

@@ -5,26 +5,27 @@ from typing import Literal
from app.database.lazer_user import User
from app.database.statistics import UserStatistics
from app.dependencies.database import Database, get_redis
from app.log import logger
from app.models.score import GameMode
from app.models.v1_user import (
GetPlayerCountResponse,
GetPlayerInfoResponse,
PlayerStatsResponse,
PlayerAllResponse,
PlayerCountData,
PlayerEventsResponse,
PlayerInfoResponse,
PlayerAllResponse,
PlayerStatsHistory,
GetPlayerCountResponse,
PlayerCountData
PlayerStatsResponse,
)
from app.models.score import GameMode
from app.log import logger
from app.router.v1.public_router import public_router, AllStrModel
from app.router.v1.public_router import public_router
from fastapi import HTTPException, Query
from fastapi.responses import JSONResponse
from sqlmodel import select
async def _create_player_mode_stats(session: Database, user: User, mode: GameMode, user_statistics: list[UserStatistics]):
async def _create_player_mode_stats(
session: Database, user: User, mode: GameMode, user_statistics: list[UserStatistics]
):
"""创建指定模式的玩家统计数据"""
from app.models.v1_user import PlayerModeStats
@@ -58,7 +59,7 @@ async def _create_player_mode_stats(session: Database, user: User, mode: GameMod
level_progress=0,
rank=0,
country_rank=0,
history=PlayerStatsHistory()
history=PlayerStatsHistory(),
)
return PlayerModeStats(
@@ -82,7 +83,7 @@ async def _create_player_mode_stats(session: Database, user: User, mode: GameMod
level_progress=0, # TODO: 计算等级进度
rank=0, # global_rank需要从RankHistory获取
country_rank=0, # country_rank需要从其他地方获取
history=PlayerStatsHistory() # TODO: 获取PP历史数据
history=PlayerStatsHistory(), # TODO: 获取PP历史数据
)
@@ -117,7 +118,7 @@ async def _create_player_info(user: User):
social_twitch=None,
social_github=None,
social_osu=None,
username_history=user.previous_usernames if user.previous_usernames else []
username_history=user.previous_usernames if user.previous_usernames else [],
)
@@ -156,11 +157,7 @@ async def _count_online_users_optimized(redis):
logger.warning(f"Redis SCAN reached max iterations ({max_iterations}), breaking")
break
cursor, keys = await redis.scan(
cursor,
match="metadata:online:*",
count=batch_size
)
cursor, keys = await redis.scan(cursor, match="metadata:online:*", count=batch_size)
online_count += len(keys)
scan_iterations += 1
@@ -208,59 +205,45 @@ async def api_get_player_info(
if not user:
from fastapi.responses import JSONResponse
return JSONResponse(
status_code=200,
content={"status": "Player not found."}
)
return JSONResponse(status_code=200, content={"status": "Player not found."})
try:
if scope == "stats":
# 获取所有模式的统计数据
user_statistics = list((
await session.exec(
select(UserStatistics).where(UserStatistics.user_id == user.id)
)
).all())
user_statistics = list(
(await session.exec(select(UserStatistics).where(UserStatistics.user_id == user.id))).all()
)
stats_dict = {}
# 获取所有游戏模式的统计数据
all_modes = [GameMode.OSU, GameMode.TAIKO, GameMode.FRUITS, GameMode.MANIA,
GameMode.OSURX, GameMode.OSUAP]
all_modes = [GameMode.OSU, GameMode.TAIKO, GameMode.FRUITS, GameMode.MANIA, GameMode.OSURX, GameMode.OSUAP]
for mode in all_modes:
mode_stats = await _create_player_mode_stats(session, user, mode, user_statistics)
stats_dict[str(int(mode))] = mode_stats
return GetPlayerInfoResponse(
player=PlayerStatsResponse(stats=stats_dict)
)
return GetPlayerInfoResponse(player=PlayerStatsResponse(stats=stats_dict))
elif scope == "events":
# 获取事件数据
events = await _get_player_events(session, user.id)
return GetPlayerInfoResponse(
player=PlayerEventsResponse(events=events)
)
return GetPlayerInfoResponse(player=PlayerEventsResponse(events=events))
elif scope == "info":
# 获取基本信息
info = await _create_player_info(user)
return GetPlayerInfoResponse(
player=PlayerInfoResponse(info=info)
)
return GetPlayerInfoResponse(player=PlayerInfoResponse(info=info))
elif scope == "all":
# 获取所有信息
# 统计数据
user_statistics = list((
await session.exec(
select(UserStatistics).where(UserStatistics.user_id == user.id)
)
).all())
user_statistics = list(
(await session.exec(select(UserStatistics).where(UserStatistics.user_id == user.id))).all()
)
stats_dict = {}
all_modes = [GameMode.OSU, GameMode.TAIKO, GameMode.FRUITS, GameMode.MANIA,
GameMode.OSURX, GameMode.OSUAP]
all_modes = [GameMode.OSU, GameMode.TAIKO, GameMode.FRUITS, GameMode.MANIA, GameMode.OSURX, GameMode.OSUAP]
for mode in all_modes:
mode_stats = await _create_player_mode_stats(session, user, mode, user_statistics)
@@ -272,13 +255,7 @@ async def api_get_player_info(
# 事件
events = await _get_player_events(session, user.id)
return GetPlayerInfoResponse(
player=PlayerAllResponse(
info=info,
stats=stats_dict,
events=events
)
)
return GetPlayerInfoResponse(player=PlayerAllResponse(info=info, stats=stats_dict, events=events))
except Exception as e:
logger.error(f"Error processing get_player_info for user {user.id}: {e}")
@@ -325,9 +302,8 @@ async def api_get_player_count(
else:
logger.debug("Cache miss, querying database for total user count")
from sqlmodel import func, select
total_count_result = await session.exec(
select(func.count()).select_from(User)
)
total_count_result = await session.exec(select(func.count()).select_from(User))
total_count = total_count_result.one()
await redis.setex(cache_key, 3600, str(total_count))
@@ -336,7 +312,7 @@ async def api_get_player_count(
return GetPlayerCountResponse(
counts=PlayerCountData(
online=online_count,
total=max(0, total_count - 1) # 减去1个机器人账户确保不为负数
total=max(0, total_count - 1), # 减去1个机器人账户确保不为负数
)
)

View File

@@ -3,31 +3,23 @@ from __future__ import annotations
from datetime import datetime
from typing import Literal
from app.database.events import Event, EventType
from app.database.lazer_user import User
from app.database.rank_history import RankHistory, RankHistoryResp
from app.database.statistics import UserStatistics, UserStatisticsResp
from app.dependencies.database import Database, get_redis
from app.log import logger
from app.models.score import GameMode
from app.models.v1_user import (
GetPlayerInfoResponse,
PlayerAllResponse,
PlayerEventItem,
PlayerEventsResponse,
PlayerInfo,
PlayerInfoResponse,
PlayerModeStats,
PlayerStatsHistory,
PlayerStatsResponse,
)
from app.service.user_cache_service import get_user_cache_service
from .router import AllStrModel, router
from fastapi import BackgroundTasks, HTTPException, Query
from pydantic import BaseModel, Field
from sqlmodel import col, select
from sqlmodel import select
class V1User(AllStrModel):
@@ -171,16 +163,14 @@ async def get_user(
# 以下为 get_player_info 接口相关的实现函数
async def _get_pp_history_for_mode(session: Database, user_id: int, mode: GameMode, days: int = 30) -> list[float]:
"""获取指定模式的 PP 历史数据"""
try:
# 获取最近 30 天的排名历史(由于没有 PP 历史,我们使用当前的 PP 填充)
stats = (
await session.exec(
select(UserStatistics).where(
UserStatistics.user_id == user_id,
UserStatistics.mode == mode
)
select(UserStatistics).where(UserStatistics.user_id == user_id, UserStatistics.mode == mode)
)
).first()
@@ -193,10 +183,7 @@ async def _get_pp_history_for_mode(session: Database, user_id: int, mode: GameMo
async def _create_player_mode_stats(
session: Database,
user: User,
mode: GameMode,
user_statistics: list[UserStatistics]
session: Database, user: User, mode: GameMode, user_statistics: list[UserStatistics]
) -> PlayerModeStats:
"""创建单个模式的玩家统计数据"""
# 查找对应模式的统计数据
@@ -230,12 +217,13 @@ async def _create_player_mode_stats(
level_progress=0,
rank=0,
country_rank=0,
history=PlayerStatsHistory(pp=pp_history)
history=PlayerStatsHistory(pp=pp_history),
)
# 获取排名信息
try:
from app.database.statistics import get_rank
global_rank = await get_rank(session, stats) or 0
country_rank = await get_rank(session, stats, user.country_code) or 0
except Exception as e:
@@ -271,7 +259,7 @@ async def _create_player_mode_stats(
level_progress=level_progress,
rank=global_rank,
country_rank=country_rank,
history=PlayerStatsHistory(pp=pp_history)
history=PlayerStatsHistory(pp=pp_history),
)
@@ -315,5 +303,5 @@ async def _create_player_info(user: User) -> PlayerInfo:
social_twitch=None,
social_github=None,
social_osu=None,
username_history=user.previous_usernames or []
username_history=user.previous_usernames or [],
)

View File

@@ -19,8 +19,8 @@ from app.router import (
private_router,
redirect_api_router,
)
from app.router.v1 import api_v1_public_router
from app.router.redirect import redirect_router
from app.router.v1 import api_v1_public_router
from app.scheduler.cache_scheduler import start_cache_scheduler, stop_cache_scheduler
from app.scheduler.database_cleanup_scheduler import (
start_database_cleanup_scheduler,