Files
gh-christianlouis-leagueledger/app/views/leaderboard.py
T
Christian Krakau-Louis d595b468e9 Add Impressum and QR code management templates
- Created a new Impressum page with legal information and contact details.
- Developed admin link page for linking QR codes to events with form functionality.
- Implemented QR code dashboard for managing QR code sets, including creation and quick actions.
- Added detailed view for QR code sets, allowing addition of QR codes and management actions.
- Introduced static file serving for favicon and related images.
- Established views for static content pages (about, contact, privacy, terms).
- Implemented translation management scripts for compiling and updating translations.
2025-04-14 03:19:41 +02:00

87 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""
Leaderboard views for displaying team rankings.
"""
from fastapi import APIRouter, Depends, Request, Query
from fastapi.responses import HTMLResponse
from sqlalchemy.orm import Session
from sqlalchemy import func, desc
from datetime import datetime, timedelta
from ..db import SessionLocal
from ..models import Team, TeamMembership, QRCode
from ..templates_config import templates
router = APIRouter()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@router.get("/", response_class=HTMLResponse)
async def show_leaderboard(
request: Request,
timeframe: str = Query("all", regex="^(week|month|all)$"),
db: Session = Depends(get_db)
):
"""Show the leaderboard with team rankings."""
# Define cutoff date based on timeframe
cutoff_date = None
if timeframe == "week":
cutoff_date = datetime.now() - timedelta(days=7)
time_label = "This Week"
elif timeframe == "month":
cutoff_date = datetime.now() - timedelta(days=30)
time_label = "This Month"
else:
timeframe = "all" # Ensure valid value
time_label = "All Time"
# Base query to get teams
query = db.query(
Team.id,
Team.name,
func.coalesce(func.sum(QRCode.points), 0).label('total_points')
).join(
QRCode,
QRCode.redeemed_at_team == Team.id,
isouter=True
)
# Apply time filter if needed
if cutoff_date:
# Filter by redeemed_at timestamp if available
query = query.filter(QRCode.redeemed_at >= cutoff_date)
# Group and order
teams_ranking = query.group_by(Team.id).order_by(desc('total_points')).all()
# Add ranks
ranked_teams = []
for idx, team in enumerate(teams_ranking):
ranked_teams.append({
'rank': idx + 1,
'id': team.id,
'name': team.name,
'points': team.total_points,
'change': 0 # Placeholder for rank change - would require historical data
})
# Get top 3 teams for podium display
top_teams = ranked_teams[:3] if len(ranked_teams) >= 3 else ranked_teams + [None] * (3 - len(ranked_teams))
return templates.TemplateResponse(
"leaderboard.html",
{
"request": request,
"teams": ranked_teams,
"top_teams": top_teams,
"timeframe": timeframe,
"time_label": time_label
}
)