mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 14:04:20 +01:00
Scoreboard optimizations (#1475)
* The top scoreboard endpoint `/api/v1/scoreboard/top/<count>` is now more performant (3x) due to better response generation In local testing I went from 3.5s to 1.2s.
This commit is contained in:
@@ -9,7 +9,8 @@
|
||||
* Add `/api/v1/challenges?view=admin` to allow admin users to see all challenges regardless of their visibility state
|
||||
* Add `/api/v1/users?view=admin` to allow admin users to see all users regardless of their hidden/banned state
|
||||
* Add `/api/v1/teams?view=admin` to allow admin users to see all teams regardless of their hidden/banned state
|
||||
* The scoreboard endpoint `/api/v1/scoreboard` is now significantly more performant due to better response generation
|
||||
* The scoreboard endpoint `/api/v1/scoreboard` is now significantly more performant (20x) due to better response generation
|
||||
* The top scoreboard endpoint `/api/v1/scoreboard/top/<count>` is now more performant (3x) due to better response generation
|
||||
* The scoreboard endpoint `/api/v1/scoreboard` will no longer show hidden/banned users in a non-hidden team
|
||||
|
||||
**Deployment**
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from collections import defaultdict
|
||||
|
||||
from flask_restx import Namespace, Resource
|
||||
|
||||
from sqlalchemy.orm import joinedload
|
||||
@@ -119,15 +121,11 @@ class ScoreboardDetail(Resource):
|
||||
solves = solves.all()
|
||||
awards = awards.all()
|
||||
|
||||
for i, team in enumerate(team_ids):
|
||||
response[i + 1] = {
|
||||
"id": standings[i].account_id,
|
||||
"name": standings[i].name,
|
||||
"solves": [],
|
||||
}
|
||||
# Build a mapping of accounts to their solves and awards
|
||||
solves = solves + awards
|
||||
solves_mapper = defaultdict(list)
|
||||
for solve in solves:
|
||||
if solve.account_id == team:
|
||||
response[i + 1]["solves"].append(
|
||||
solves_mapper[solve.account_id].append(
|
||||
{
|
||||
"challenge_id": solve.challenge_id,
|
||||
"account_id": solve.account_id,
|
||||
@@ -137,20 +135,17 @@ class ScoreboardDetail(Resource):
|
||||
"date": isoformat(solve.date),
|
||||
}
|
||||
)
|
||||
for award in awards:
|
||||
if award.account_id == team:
|
||||
response[i + 1]["solves"].append(
|
||||
{
|
||||
"challenge_id": None,
|
||||
"account_id": award.account_id,
|
||||
"team_id": award.team_id,
|
||||
"user_id": award.user_id,
|
||||
"value": award.value,
|
||||
"date": isoformat(award.date),
|
||||
}
|
||||
)
|
||||
response[i + 1]["solves"] = sorted(
|
||||
response[i + 1]["solves"], key=lambda k: k["date"]
|
||||
|
||||
# Sort all solves by date
|
||||
for team_id in solves_mapper:
|
||||
solves_mapper[team_id] = sorted(
|
||||
solves_mapper[team_id], key=lambda k: k["date"]
|
||||
)
|
||||
|
||||
for i, team in enumerate(team_ids):
|
||||
response[i + 1] = {
|
||||
"id": standings[i].account_id,
|
||||
"name": standings[i].name,
|
||||
"solves": solves_mapper.get(standings[i].account_id, []),
|
||||
}
|
||||
return {"success": True, "data": response}
|
||||
|
||||
Reference in New Issue
Block a user