Implement /api/v1/leaderboard
This commit is contained in:
parent
896de75ac7
commit
2456e2b4ec
3 changed files with 74 additions and 1 deletions
16
database.py
16
database.py
|
|
@ -1,4 +1,4 @@
|
|||
from sqlalchemy import create_engine, Column, String, Integer, Boolean, DateTime, ForeignKey, Text, BigInteger
|
||||
from sqlalchemy import create_engine, Column, String, Integer, Boolean, DateTime, ForeignKey, Text, BigInteger, Float, func
|
||||
from sqlalchemy.orm import declarative_base, sessionmaker
|
||||
from sqlalchemy.exc import OperationalError
|
||||
from config import settings
|
||||
|
|
@ -45,6 +45,20 @@ class EquipmentLast(Base):
|
|||
Rank = Column(Integer)
|
||||
Udemae = Column(Integer)
|
||||
|
||||
class PlayerRank(Base):
|
||||
__tablename__ = 'player_ranks'
|
||||
|
||||
PId = Column(BigInteger, primary_key=True, nullable=False)
|
||||
GameMode = Column(Integer, primary_key=True, nullable=False)
|
||||
MiiName = Column(String, nullable=True)
|
||||
Rank = Column(Integer, default=0)
|
||||
FesPower = Column(Float, default=0.0)
|
||||
WinSum = Column(Integer, default=0)
|
||||
LoseSum = Column(Integer, default=0)
|
||||
RankingScore = Column(Float, default=0.0)
|
||||
createdAt = Column(DateTime, server_default=func.now())
|
||||
updatedAt = Column(DateTime, onupdate=func.now())
|
||||
|
||||
engine = create_engine(settings.db_url, pool_pre_ping=True)
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
|
|
|
|||
2
main.py
2
main.py
|
|
@ -11,6 +11,7 @@ from routes import me
|
|||
from routes.equipment import equipment_history
|
||||
from routes.equipment import equipment
|
||||
from services.boss_retrieval import process_boss_file
|
||||
from routes import Ranking
|
||||
from contextlib import asynccontextmanager
|
||||
import asyncio
|
||||
import subprocess
|
||||
|
|
@ -119,6 +120,7 @@ app.include_router(boss.router, prefix="/api/v1")
|
|||
app.include_router(me.router, prefix="/api/v1")
|
||||
app.include_router(equipment_history.router, prefix="/api/v1")
|
||||
app.include_router(equipment.router, prefix="/api/v1")
|
||||
app.include_router(Ranking.router, prefix="/api/v1")
|
||||
|
||||
if __name__ == '__main__':
|
||||
uvicorn.run("main:app", host="0.0.0.0", port=settings.port, reload=True)
|
||||
57
routes/Ranking.py
Normal file
57
routes/Ranking.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm import Session as DBSession
|
||||
from sqlalchemy import desc
|
||||
from database import SessionLocal, PlayerRank
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
def get_db():
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
@router.get("/leaderboard")
|
||||
async def get_leaderboard(db: DBSession = Depends(get_db)):
|
||||
try:
|
||||
top_100_query = (
|
||||
db.query(PlayerRank.PId)
|
||||
.order_by(desc(PlayerRank.FesPower))
|
||||
.limit(100)
|
||||
.all()
|
||||
)
|
||||
top_100_pids = {row for row in top_100_query}
|
||||
modes = [0, 1, 2]
|
||||
|
||||
leaderboard = {}
|
||||
|
||||
for mode in modes:
|
||||
top_players = (
|
||||
db.query(PlayerRank)
|
||||
.filter(PlayerRank.GameMode == mode)
|
||||
.order_by(desc(PlayerRank.RankingScore))
|
||||
.limit(9)
|
||||
.all()
|
||||
)
|
||||
|
||||
mode_results = []
|
||||
for player in top_players:
|
||||
mode_results.append({
|
||||
"PId": player.PId,
|
||||
"MiiName": player.MiiName,
|
||||
"Rank": player.Rank,
|
||||
"WinSum": player.WinSum,
|
||||
"LoseSum": player.LoseSum,
|
||||
"RankingScore": round(player.RankingScore, 2),
|
||||
"FesPower": player.FesPower,
|
||||
"is_top_100_fes": player.PId in top_100_pids
|
||||
})
|
||||
|
||||
leaderboard[f"mode_{mode}"] = mode_results
|
||||
|
||||
return leaderboard
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error fetching leaderboard: {e}")
|
||||
return {"error": str(e)}
|
||||
Loading…
Reference in a new issue